package org.example.service;


import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import lombok.extern.slf4j.Slf4j;
import org.example.annonation.PoiTlLoopTable;
import org.example.annonation.PoiTlSymbol;
import org.example.annonation.PoiTlText;
import org.example.util.PoiTlUtil;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class PoiTlService {

    public void write(OutputStream outputStream, Object template, InputStream templateInputStream) {
        try {
            getXWPFTemplate(template, templateInputStream).writeAndClose(outputStream);
        } catch (Exception e) {
            log.error("PoiTlService.download is error ", e);
            throw new RuntimeException("下载word失败！");
        }
    }

    private XWPFTemplate getXWPFTemplate(Object template, InputStream inputStream) {
        ConfigureBuilder builder = Configure.builder();
        Map<String, Object> wordDataMap;
        try {
            wordDataMap = getWordDataMap(template, builder);
        } catch (Exception e) {
            log.debug("template  :  {}", template);
            log.error("PoiTlService.getXWPFTemplate is error ", e);
            throw new RuntimeException("转换word数据失败！");
        }
        XWPFTemplate xwpfTemplate = XWPFTemplate.compile(inputStream, builder.build()).render(wordDataMap);
        return xwpfTemplate;
    }


    private Map<String, Object> getWordDataMap(Object template, ConfigureBuilder configureBuilder) throws Exception {
        Map<String, Object> wordDataMap = new HashMap<>();
        if (template == null) {
            return wordDataMap;
        }
        Class<?> templateClass = template.getClass();
        Field[] declaredFields = templateClass.getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            Object fieldData = field.get(template);
            PoiTlSymbol symbol = field.getAnnotation(PoiTlSymbol.class);
            if (symbol != null) {
                wordDataMap.putAll(PoiTlUtil.symbolEvent(symbol, fieldData));
                continue;
            }
            PoiTlText annotation = field.getAnnotation(PoiTlText.class);
            if (annotation != null) {
                wordDataMap.putAll(PoiTlUtil.getText(fieldData));
                continue;
            }
            PoiTlLoopTable loopTable = field.getAnnotation(PoiTlLoopTable.class);
            if (loopTable != null) {
                wordDataMap.putAll(PoiTlUtil.loopTableEvent(loopTable.value(), fieldData));
                configureBuilder.bind(loopTable.value(), PoiTlUtil.loopTablePolicy(loopTable.direction()));
            }
        }
        return wordDataMap;

    }


}
